#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "sqlite3.h"

#define BACKLOG 13

void print_usage(char *progname);
void sig_stop(int signum);

int g_stop =0;

int main(int argc,char *argv[])
{
	int                     rv;
	int                     ret;
	int                     opt;
        int                     idx;
	int                     port;
        int                     log_fd;
        int                     ch = 1;
        int                     daemon_run = 0;
        int                     ser_fd = -1;
        int                     cli_fd = -1;
        pid_t                   pid = -1;
        struct sockaddr_in      ser_addr;
        struct sockaddr_in      cli_addr;
        socklen_t               cliaddr_len =20;

	struct option            opts[]={
		{"daemon",no_argument,NULL,'d'},    //deamon:程序后台运行
		{"port",required_argument,NULL,'p'},//port:指定服务器开端口
		{"help",no_argument,NULL,'h'},      //help:打印帮助信息
		{NULL,0,NULL,0}
	};

	while((opt=getopt_long(argc,argv,"dp:h",opts,&idx)) != -1)
	{
		switch(opt)
		{
			case 'd':
				daemon_run=1;
				break;
			case 'p':
				port=atoi(optarg);
				break;
			case 'h':
				print_usage(argv[0]);
				return 0;
		}
	}

if(!port)
{
	print_usage(argv[0]);
	return 0;
}

if(daemon_run)
{
	printf("Program %s is running at the background now\n",argv[0]);

	log_fd=open("receive_temper.log",O_CREAT|O_RDWR, 0666);
	if (log_fd,0)
	{
		printf("Open the logfile failure: %s/n",strerror(errno));
		return 0;
	}

        dup2(log_fd, STDOUT_FILENO);
        dup2(log_fd, STDERR_FILENO);

	if((daemon(1,1))<0)
	{
	        printf("Deamon failure : %s\n", strerror(errno));
		return 0;
	}
}

        signal(SIGUSR1, sig_stop);

	ser_fd=socket(AF_INET,SOCK_STREAM,0);
	if (ser_fd<0)
	{
	       printf("Creat failure:%s\n",strerror(errno));
	       return 0;
	}
        printf("Creat the ser_fd[%d]!\n",ser_fd);

        memset(&ser_addr, 0, sizeof(ser_addr));
        ser_addr.sin_family = AF_INET;		
        ser_addr.sin_port = htons(port);	
        ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	setsockopt(ser_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ch, sizeof(ch));

        rv= bind(ser_fd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));
	if(rv<0)
        {
	       printf("Bind failure:%s\n",strerror(errno));
               return 0;
	}
        printf("The port[%d] has been bind by this server!\n",port);

        listen(ser_fd,BACKLOG);

	while(!g_stop)
        {
		 cli_fd = accept(ser_fd, (struct sockaddr *)&cli_addr, &cliaddr_len);
		 if (cli_fd < 0)
		 {
			 printf("Accept the request from client failure:%s\n", strerror(errno));
			 continue;
		 }
		 
		 pid=fork();
		 if(pid<0)
		 {
			 printf("Creat child process failure:%s.\n", strerror(errno));
			 continue;
		 }
		 else if(pid>0)
		 {
			 close(cli_fd);
			 continue;
		 }
		 else if(pid==0)
		 {
			 close(ser_fd);


		int         a;
		int         len;
	        char        *sn;
                char        *cut;
                char        *temp; 
                char        buf[512];
                char        *datetime;
                char        *zErrMsg = NULL;
                char        sql1[128];
		char        *sql="create table if not exists temperature(sn char(10), datetime char(50), temperature  char(10))";			
                sqlite3     *db = NULL;

		len = sqlite3_open("temper.db",&db); 
		if(len)
		{
			fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
	                sqlite3_close(db);
	                exit(1);
		}
		else
		{
			printf("You have opened a sqlite3 database named temper.db successfully!\n");
		}

		ret = sqlite3_exec(db, sql, 0, 0, &zErrMsg);
                if (ret != SQLITE_OK)
                {
	                sqlite3_close(db);
	                printf("Creat table failure \n");
	                return 0;
                 }
	                printf("Create table successfully!\n");
	                printf("Child process start to communicate with client by cli_fd[%d]...\n", cli_fd);
	                printf("Now ready to connect the client and recive message from client...\n");
                        printf("\n");

			while(1)
			{
								         
			memset(buf,0,sizeof(buf));
                        a=read(cli_fd,buf,sizeof(buf));
                  if(a<0)
		  {
                        printf("Read information from client failure:%s\n", strerror(errno));
                        close(cli_fd);
                        exit(0);
		  }
                  else if(a==0)
		  {
	                printf("The connection with client has broken!\n");
                        close(cli_fd);
                        exit(0);
		  }
		  else 
		  {
	                printf("The message recived from client[%s,%d] is \"%s\"\n",
                        inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buf);
                        cut = strtok(buf,"/");
                   if(cut !=NULL)
		   {
			sn=cut;
		        if((cut = strtok(NULL,"/")) !=NULL)
			{
				temp=cut;
				//printf("%s\n",temp);
			}	
		   }			   

		  }
		   snprintf(sql1, 128, "insert into temperature values('%s', '%s', '%s');", sn, datetime, temp);
		   sql1[127] = '\0';
                   printf("%s\n", sql1);
                   //将数据存储至temperature表中
                   ret = sqlite3_exec(db, sql1, 0 , 0, &zErrMsg);
		   if (ret != SQLITE_OK)
                   {
                         sqlite3_close(db);
			 if (ret != SQLITE_OK)
			 {
				 sqlite3_close(db);
				 printf("insert data failure ； %s!\n", zErrMsg);     
			      	 return 0;
	                  }                                                                                        
	       		 printf("insert data successfully!\n");
			 printf("\n");
		   }
		 }
	     }
	}

             close (ser_fd);
	     return 0;
}

void print_usage(char *progneme)
{
	 printf("-d(--daemon):let program run in the background.\n"); 
         printf("-p(--port):enter server port.\n");
         printf("-h(--help):print this help information.\n"); 
         
	 return ;
}

void sig_stop(int signum)
{
         if(SIGUSR1 == signum)
	 {
		g_stop = 1;
	 }
	 return ;
}












